package co.edu.eam.iso.view;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.DefaultCellEditor;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;

import co.edu.eam.iso.enums.ActionEnum;
import co.edu.eam.iso.enums.CharacteristicEnum;
import co.edu.eam.iso.enums.IconEnum;
import co.edu.eam.iso.enums.ScaleEnum;
import co.edu.eam.iso.enums.SubCharacteristicEnum;
import co.edu.eam.iso.evaluated.ProductEvaluated;
import co.edu.eam.iso.evaluator.Characteristic;
import co.edu.eam.iso.evaluator.Evaluator;
import co.edu.eam.iso.evaluator.Metric;
import co.edu.eam.iso.evaluator.SubCharacteristic;
import co.edu.eam.iso.util.BigDecimalUtil;

public class EvaluateChrtcs extends JDialog {

	/**
	 * Number of class serialization.
	 */
	private static final long serialVersionUID = 1L;
	
	private static final int LABEL_WIDTH = 90;
	
	private static final int LABEL_HEIGHT = 16;

	private DefaultTableModel tableModelFunctionality;
	private DefaultTableModel tableModelReliability;
	private DefaultTableModel tableModelUsability;
	private DefaultTableModel tableModelEfficiency;
	private DefaultTableModel tableModelMaintainability;
	private DefaultTableModel tableModelPortability;
		
	private List<Metric> functionalityMetrics;
	private List<Metric> reliabilityMetrics; 
	private List<Metric> usabilityMetrics;
	private List<Metric> efficiencyMetrics;
	private List<Metric> maintainabilityMetrics;
	private List<Metric> portabilityMetrics;
	
	private JButton btnModifyValueEfficiency;
	private JButton btnRestoreValueEfficiency;
	private JButton btnChrtcsModify;
	private JButton btnChrtcsRestore;
	private JButton btnRemoveMetricEfficiency;
	private JButton btnAddMetricEfficiency;
	private JButton btnRestoreValueFunctionality;
	private JButton btnModifyValueFunctionality;
	private JButton btnRemoveMetricFunctionality;
	private JButton btnAddMetricFunctionality;
	private JButton btnAddMetricReliability;
	private JButton btnModifyValueReliability;
	private JButton btnRestoreValueReliability;
	private JButton btnRemoveMetricReliability;
	private JButton btnModifyValueUsability;
	private JButton btnRestoreValueUsability;
	private JButton btnAddMetricUsability;
	private JButton btnRemoveMetricUsability;
	private JButton btnModifyValueMaintainability;
	private JButton btnRestoreValueMaintainability;
	private JButton btnAddMetricMaintainability;
	private JButton btnRemoveMetricMaintainability;
	private JButton btnModifyValuePortability;
	private JButton btnRestoreValuePortability;
	private JButton btnAddMetricPortability;
	private JButton btnRemoveMetricPortability;
	
	private JComboBox cbScales;
		
	private JLabel lblTotalValueChrtcs;
	private JLabel lblTotalValueEfficiency;
	private JLabel lblTotalValueFunctionality;
	private JLabel lblTotalValueReliability;
	private JLabel lblTotalValueUsability;
	private JLabel lblTotalValueMaintainability;
	private JLabel lblTotalValuePortability;

	private JTable tblMetricsEfficiency;
	private JTable tblMetricsFunctionality;
	private JTable tblMetricsReliability;
	private JTable tblMetricsUsability;
	private JTable tblMetricsMaintainability;
	private JTable tblMetricsPortability;
	
	private JTextField txtValueFunctionality;
	private JTextField txtValueUsability;
	private JTextField txtValueReliability;
	private JTextField txtValueEfficiency;
	private JTextField txtValueMaintainability;
	private JTextField txtValuePortability;
	private JTextField txtValueAccuracy;
	private JTextField txtValueInteroperability;
	private JTextField txtValueSecurity;
	private JTextField txtValueSuitability;
	private JTextField txtValueFaultTolerance;
	private JTextField txtValueRecoverability;
	private JTextField txtValueMaturity;
	private JTextField txtValueLearnability;
	private JTextField txtValueOperability;
	private JTextField txtValueAttractiveness;
	private JTextField txtValueUnderstandability;
	private JTextField txtValueResourceUtilisation;
	private JTextField txtValueTimeBehaviour;
	private JTextField txtValueChangeability;
	private JTextField txtValueStability;
	private JTextField txtValueTestability;
	private JTextField txtValueAnalyzability;
	private JTextField txtValueInstallability;
	private JTextField txtValueCoExistence;
	private JTextField txtValueReplaceability;
	private JTextField txtValueAdaptability;
	
	/**
	 * Characteristics to evaluate.
	 */
	private Map<CharacteristicEnum, Characteristic> characteristics;

	private int[][] coordinates;
	
	private Metric selectedMetric;

	/**
	 * Create the frame.
	 * 
	 * @param parent
	 * @param characteristics
	 */
	public EvaluateChrtcs(SelectChrtcs parent,
			Map<CharacteristicEnum, Characteristic> characteristics) {
		this.cbScales = new JComboBox(ScaleEnum.values());
		this.characteristics = characteristics;
		this.coordinates = new int[characteristics.size()][];
		calculateCoordinates();
		initialize(parent);
	}

	private void initialize(SelectChrtcs parent) {
		setTitle("ISO 9126-1 - Evaluar producto");
		setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
		setModalityType(ModalityType.APPLICATION_MODAL);
		setBounds(100, 100, 800, 499);
		setLocationRelativeTo(parent);
		setResizable(false);
		setContentPane(createContentPanel());
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				closeWindow();
			}
		});
	}
	
	private JPanel createContentPanel() {
		JPanel contentPane = new JPanel();
		contentPane.setLayout(null);
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

		contentPane.add(createPanelValueChrtcs());
		contentPane.add(createTabsCharacteristics());

		JButton btnCancel = new JButton("Cancelar");
		btnCancel.setBounds(598, 439, 90, 25);
		btnCancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				closeWindow();
			}
		});
		contentPane.add(btnCancel);

		JButton btnEvaluate = new JButton("Evaluar");
		btnEvaluate.setBounds(690, 439, 90, 25);
		btnEvaluate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				evaluate();
			}
		});
		contentPane.add(btnEvaluate);

		return contentPane;
	}
	
	private JPanel createPanelValueChrtcs() {
		int count = -1;
		JPanel panelValuesChrtcs = new JPanel();
		panelValuesChrtcs.setLayout(null);
		panelValuesChrtcs.setBounds(10, 10, 770, 112);
		panelValuesChrtcs.setBorder(new TitledBorder(null,
				"Valor por caracter\u00EDstica (%)", TitledBorder.LEADING,
				TitledBorder.TOP, null, new Color(59, 59, 59)));
		
		if (characteristics.containsKey(CharacteristicEnum.FUNCTIONALITY)) 
			createValueFunctionality(panelValuesChrtcs, coordinates[++count]);

		if (characteristics.containsKey(CharacteristicEnum.RELIABILITY))
			createValueReliability(panelValuesChrtcs, coordinates[++count]);

		if (characteristics.containsKey(CharacteristicEnum.USABILITY))
			createValueUsability(panelValuesChrtcs, coordinates[++count]);

		if (characteristics.containsKey(CharacteristicEnum.EFFICIENCY))
			createValueEfficiency(panelValuesChrtcs, coordinates[++count]);

		if (characteristics.containsKey(CharacteristicEnum.MAINTAINABILITY))
			createValueMaintainability(panelValuesChrtcs, coordinates[++count]);

		if (characteristics.containsKey(CharacteristicEnum.PORTABILITY))
			createValuePortability(panelValuesChrtcs, coordinates[++count]);	
		
		btnChrtcsRestore = new JButton();
		btnChrtcsRestore.setEnabled(false);
		btnChrtcsRestore.setToolTipText("Restablecer");
		btnChrtcsRestore.setIcon(getIcon(IconEnum.RESTORE));
		btnChrtcsRestore.setBounds(15, 61, 35, 35);
		btnChrtcsRestore.setFocusable(false);
		btnChrtcsRestore.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				BigDecimal weight = new BigDecimal(100.00 / characteristics.size());
				weight = weight.setScale(2, RoundingMode.HALF_UP);
				modifyValueCharacteristics(false, weight.toString(), "Total:     100");
				btnChrtcsModify.setEnabled(true);
				btnChrtcsRestore.setEnabled(false);
				btnChrtcsModify.requestFocus();
			}
		});
		panelValuesChrtcs.add(btnChrtcsRestore);
		
		btnChrtcsModify = new JButton();
		btnChrtcsModify.setBounds(15, 25, 35, 35);
		btnChrtcsModify.setToolTipText("Modificar");
		btnChrtcsModify.setEnabled(characteristics.size() == 1 ? false : true);
		btnChrtcsModify.setIcon(getIcon(IconEnum.MODIFY));
		btnChrtcsModify.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				modifyValueCharacteristics(true, "0", "Total:     0");
				btnChrtcsRestore.setEnabled(true);
				btnChrtcsModify.setEnabled(false);
			}
		});
		panelValuesChrtcs.add(btnChrtcsModify);
		
		lblTotalValueChrtcs = new JLabel("Total:     100");
		lblTotalValueChrtcs.setBounds(682, 80, 70, 15);
		lblTotalValueChrtcs.setFont(new Font("SansSerif", Font.BOLD, 12));
		panelValuesChrtcs.add(lblTotalValueChrtcs);	
		
		return  panelValuesChrtcs;		
	}

	private JTabbedPane createTabsCharacteristics() {
		JTabbedPane tabbedPaneEvaluateChrtcs = new JTabbedPane(JTabbedPane.TOP);
		tabbedPaneEvaluateChrtcs.setBounds(10, 124, 775, 315);

		if (characteristics.containsKey(CharacteristicEnum.FUNCTIONALITY)) {
			functionalityMetrics = new ArrayList<Metric>();
			tableModelFunctionality = createTableModel();
			tabbedPaneEvaluateChrtcs.addTab("Funcionalidad", null,
					createTabFunctionality(), null);
		}

		if (characteristics.containsKey(CharacteristicEnum.RELIABILITY)) {
			reliabilityMetrics = new ArrayList<Metric>();
			tableModelReliability = createTableModel();
			tabbedPaneEvaluateChrtcs.addTab("Fiabilidad", null,
					createTabReliability(), null);
		}

		if (characteristics.containsKey(CharacteristicEnum.USABILITY)) {
			usabilityMetrics = new ArrayList<Metric>();
			tableModelUsability = createTableModel();
			tabbedPaneEvaluateChrtcs.addTab("Usabilidad", null,
					createTabUsability(), null);
		}

		if (characteristics.containsKey(CharacteristicEnum.EFFICIENCY)) {
			efficiencyMetrics = new ArrayList<Metric>();
			tableModelEfficiency = createTableModel();
			tabbedPaneEvaluateChrtcs.addTab("Eficiencia", null,
					createTabEfficiency(), null);
		}

		if (characteristics.containsKey(CharacteristicEnum.MAINTAINABILITY)) {
			maintainabilityMetrics = new ArrayList<Metric>();
			tableModelMaintainability = createTableModel();
			tabbedPaneEvaluateChrtcs.addTab("Mantenibilidad", null,
					createTabMaintainability(), null);
		}

		if (characteristics.containsKey(CharacteristicEnum.PORTABILITY)) {
			portabilityMetrics = new ArrayList<Metric>();
			tableModelPortability = createTableModel(); 
			tabbedPaneEvaluateChrtcs.addTab("Portabilidad", null,
					createTabPortability(), null);
		}

		return tabbedPaneEvaluateChrtcs;
	}

	private JPanel createTabFunctionality() {		
		JPanel tabFunctionality = new JPanel();
		tabFunctionality.setLayout(null);

		JPanel panelValueFunctionality = new JPanel();
		panelValueFunctionality.setLayout(null);
		panelValueFunctionality.setBounds(0, 6, 265, 270);
		panelValueFunctionality.setBorder(new TitledBorder(null,
				"Valor por sub-caracter\u00EDstica (%)", TitledBorder.LEADING,
				TitledBorder.TOP, null, new Color(59, 59, 59)));
		tabFunctionality.add(panelValueFunctionality);

		txtValueAccuracy = new JTextField();
		txtValueAccuracy.setEditable(false);
		txtValueAccuracy.setText("25.00");
		txtValueAccuracy.setBounds(200, 55, 50, 25);
		panelValueFunctionality.add(txtValueAccuracy);

		JLabel lblValueAccuracy = new JLabel("Exactitud:");
		lblValueAccuracy.setBounds(60, 60, 128, 16);
		panelValueFunctionality.add(lblValueAccuracy);

		JLabel lblValueInteroperability = new JLabel("Interoperabilidad:");
		lblValueInteroperability.setBounds(60, 90, 128, 16);
		panelValueFunctionality.add(lblValueInteroperability);

		txtValueInteroperability = new JTextField();
		txtValueInteroperability.setText("25.00");
		txtValueInteroperability.setEditable(false);
		txtValueInteroperability.setBounds(200, 83, 50, 25);
		panelValueFunctionality.add(txtValueInteroperability);

		JLabel lblValueSecurity = new JLabel("Seguridad:");
		lblValueSecurity.setBounds(60, 120, 128, 16);
		panelValueFunctionality.add(lblValueSecurity);

		txtValueSecurity = new JTextField();
		txtValueSecurity.setText("25.00");
		txtValueSecurity.setEditable(false);
		txtValueSecurity.setBounds(200, 111, 50, 25);
		panelValueFunctionality.add(txtValueSecurity);

		JLabel lblValueSuitability = new JLabel("Adecuación:");
		lblValueSuitability.setBounds(60, 30, 128, 16);
		panelValueFunctionality.add(lblValueSuitability);

		txtValueSuitability = new JTextField();
		txtValueSuitability.setText("25.00");
		txtValueSuitability.setEditable(false);
		txtValueSuitability.setBounds(200, 27, 50, 25);
		panelValueFunctionality.add(txtValueSuitability);
		
		btnModifyValueFunctionality = new JButton();
		btnModifyValueFunctionality.setBounds(15, 25, 35, 35);
		btnModifyValueFunctionality.setToolTipText("Modificar");
		btnModifyValueFunctionality.setIcon(getIcon(IconEnum.MODIFY));
		panelValueFunctionality.add(btnModifyValueFunctionality);
		btnModifyValueFunctionality.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnRestoreValueFunctionality.setEnabled(true);
				btnModifyValueFunctionality.setEnabled(false);
				modifyValueSubCharacteristics(true, "0",
						lblTotalValueFunctionality, "Total:     0",
						txtValueSuitability, txtValueAccuracy,
						txtValueInteroperability, txtValueSecurity);
			}
		});
		
		btnRestoreValueFunctionality = new JButton();
		btnRestoreValueFunctionality.setEnabled(false);
		btnRestoreValueFunctionality.setFocusable(false);
		btnRestoreValueFunctionality.setBounds(15, 61, 35, 35);
		btnRestoreValueFunctionality.setToolTipText("Restablecer");
		btnRestoreValueFunctionality.setIcon(getIcon(IconEnum.RESTORE));
		panelValueFunctionality.add(btnRestoreValueFunctionality);
		btnRestoreValueFunctionality.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnModifyValueFunctionality.requestFocus();
				btnModifyValueFunctionality.setEnabled(true);
				btnRestoreValueFunctionality.setEnabled(false);
				modifyValueSubCharacteristics(false, "25.00",
						lblTotalValueFunctionality, "Total:     100",
						txtValueSuitability, txtValueAccuracy,
						txtValueInteroperability, txtValueSecurity);
			}
		});
		
		lblTotalValueFunctionality = new JLabel("Total:     100");
		lblTotalValueFunctionality.setBounds(180, 235, 70, 16);
		lblTotalValueFunctionality.setFont(new Font("SansSerif", Font.BOLD, 12));
		panelValueFunctionality.add(lblTotalValueFunctionality);

		JPanel panelEvaluateFunctionality = new JPanel();
		panelEvaluateFunctionality.setLayout(null);
		panelEvaluateFunctionality.setBounds(265, 6, 505, 270);
		panelEvaluateFunctionality.setBorder(new TitledBorder(null,
				"Evaluar m\u00E9tricas", TitledBorder.LEADING,
				TitledBorder.TOP, null, new Color(59, 59, 59)));
		tabFunctionality.add(panelEvaluateFunctionality);

		tblMetricsFunctionality = new JTable();
		tblMetricsFunctionality.setRowHeight(20);
		tblMetricsFunctionality.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		tblMetricsFunctionality.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				btnRemoveMetricFunctionality.setEnabled(true);
			}
		});

		JScrollPane spEvaluateFunctionality = new JScrollPane();
		spEvaluateFunctionality.setBounds(51, 25, 435, 225);
		spEvaluateFunctionality.setViewportView(tblMetricsFunctionality);
		panelEvaluateFunctionality.add(spEvaluateFunctionality);

		btnAddMetricFunctionality = new JButton();
		btnAddMetricFunctionality.setToolTipText("Agregar");
		btnAddMetricFunctionality.setBounds(15, 25, 35, 35);
		btnAddMetricFunctionality.setIcon(getIcon(IconEnum.ADD));
		panelEvaluateFunctionality.add(btnAddMetricFunctionality);
		btnAddMetricFunctionality.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				addMetric(CharacteristicEnum.FUNCTIONALITY,
						functionalityMetrics, tableModelFunctionality);
			}
		});
		
		btnRemoveMetricFunctionality = new JButton();
		btnRemoveMetricFunctionality.setEnabled(false);
		btnRemoveMetricFunctionality.setToolTipText("Quitar");
		btnRemoveMetricFunctionality.setBounds(15, 61, 35, 35);
		btnRemoveMetricFunctionality.setIcon(getIcon(IconEnum.REMOVE));
		panelEvaluateFunctionality.add(btnRemoveMetricFunctionality);
		btnRemoveMetricFunctionality.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int row = tblMetricsFunctionality.getSelectedRow();
				removeMetric(row, functionalityMetrics);
				refreshTable(tblMetricsFunctionality, functionalityMetrics,
						tableModelFunctionality);
				btnRemoveMetricFunctionality.setEnabled(false);
			}
		});

		clearTable(tblMetricsFunctionality, tableModelFunctionality);
		setKeyListener(txtValueSuitability, txtValueAccuracy,
				txtValueInteroperability, txtValueSecurity);
		setFocusListener(lblTotalValueFunctionality, txtValueSuitability,
				txtValueAccuracy, txtValueInteroperability, txtValueSecurity);

		return tabFunctionality;
	}
		
	private JPanel createTabReliability() {
		JPanel tabReliability = new JPanel();
		tabReliability.setLayout(null);
		
		JPanel panelValueReliability = new JPanel();
		panelValueReliability.setLayout(null);
		panelValueReliability.setBorder(new TitledBorder(null,
				"Valor por sub-caracter\u00EDstica (%)", TitledBorder.LEADING,
				TitledBorder.TOP, null, new Color(59, 59, 59)));
		panelValueReliability.setBounds(0, 6, 265, 270);
		tabReliability.add(panelValueReliability);
		
		txtValueFaultTolerance = new JTextField();
		txtValueFaultTolerance.setText("33.33");
		txtValueFaultTolerance.setEditable(false);
		txtValueFaultTolerance.setBounds(200, 55, 50, 25);
		panelValueReliability.add(txtValueFaultTolerance);
		
		JLabel lblValueFaultTolerance = new JLabel("Tolerancia a fallos:");
		lblValueFaultTolerance.setBounds(60, 60, 128, 16);
		panelValueReliability.add(lblValueFaultTolerance);
		
		JLabel lblValueRecoverability = new JLabel("Recuperabilidad:");
		lblValueRecoverability.setBounds(60, 90, 128, 16);
		panelValueReliability.add(lblValueRecoverability);
		
		txtValueRecoverability = new JTextField();
		txtValueRecoverability.setText("33.33");
		txtValueRecoverability.setEditable(false);
		txtValueRecoverability.setBounds(200, 83, 50, 25);
		panelValueReliability.add(txtValueRecoverability);
		
		JLabel lblValueMaturity = new JLabel("Madurez:");
		lblValueMaturity.setBounds(60, 30, 128, 16);
		panelValueReliability.add(lblValueMaturity);
		
		txtValueMaturity = new JTextField();
		txtValueMaturity.setText("33.33");
		txtValueMaturity.setEditable(false);
		txtValueMaturity.setBounds(200, 27, 50, 25);
		panelValueReliability.add(txtValueMaturity);
		
		btnModifyValueReliability = new JButton();
		btnModifyValueReliability.setBounds(15, 25, 35, 35);
		btnModifyValueReliability.setToolTipText("Modificar");
		btnModifyValueReliability.setIcon(getIcon(IconEnum.MODIFY));
		panelValueReliability.add(btnModifyValueReliability);
		btnModifyValueReliability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnRestoreValueReliability.setEnabled(true);
				btnModifyValueReliability.setEnabled(false);
				modifyValueSubCharacteristics(true, "0",
						lblTotalValueReliability, "Total:     0",
						txtValueMaturity, txtValueFaultTolerance,
						txtValueRecoverability);
			}
		});
		
		btnRestoreValueReliability = new JButton();
		btnRestoreValueReliability.setEnabled(false);
		btnRestoreValueReliability.setFocusable(false);
		btnRestoreValueReliability.setBounds(15, 61, 35, 35);
		btnRestoreValueReliability.setToolTipText("Restablecer");
		btnRestoreValueReliability.setIcon(getIcon(IconEnum.RESTORE));
		panelValueReliability.add(btnRestoreValueReliability);
		btnRestoreValueReliability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnModifyValueReliability.requestFocus();
				btnModifyValueReliability.setEnabled(true);
				btnRestoreValueReliability.setEnabled(false);
				modifyValueSubCharacteristics(false, "33.33",
						lblTotalValueReliability, "Total:     100",
						txtValueMaturity, txtValueFaultTolerance,
						txtValueRecoverability);
			}
		});
		
		lblTotalValueReliability = new JLabel("Total:     100");
		lblTotalValueReliability.setBounds(180, 235, 70, 16);
		lblTotalValueReliability.setFont(new Font("SansSerif", Font.BOLD, 12));
		panelValueReliability.add(lblTotalValueReliability);
		
		JPanel panelEvaluateReliability = new JPanel();
		panelEvaluateReliability.setLayout(null);
		panelEvaluateReliability.setBounds(265, 6, 505, 270);
		panelEvaluateReliability.setBorder(new TitledBorder(null,
				"Evaluar m\u00E9tricas", TitledBorder.LEADING,
				TitledBorder.TOP, null, new Color(59, 59, 59)));
		tabReliability.add(panelEvaluateReliability);
				
		tblMetricsReliability = new JTable();
		tblMetricsReliability.setRowHeight(20);
		tblMetricsReliability.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		tblMetricsReliability.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				btnRemoveMetricReliability.setEnabled(true);
			}
		});		
		
		JScrollPane spEvaluateReliability = new JScrollPane();
		spEvaluateReliability.setBounds(51, 25, 435, 225);
		spEvaluateReliability.setViewportView(tblMetricsReliability);
		panelEvaluateReliability.add(spEvaluateReliability);
		
		btnAddMetricReliability = new JButton();
		btnAddMetricReliability.setToolTipText("Agregar");
		btnAddMetricReliability.setBounds(15, 25, 35, 35);
		btnAddMetricReliability.setIcon(getIcon(IconEnum.ADD));
		panelEvaluateReliability.add(btnAddMetricReliability);
		btnAddMetricReliability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				addMetric(CharacteristicEnum.RELIABILITY,
						reliabilityMetrics, tableModelReliability);
			}
		});
		
		btnRemoveMetricReliability = new JButton();
		btnRemoveMetricReliability.setEnabled(false);
		btnRemoveMetricReliability.setToolTipText("Quitar");
		btnRemoveMetricReliability.setBounds(15, 61, 35, 35);
		btnRemoveMetricReliability.setIcon(getIcon(IconEnum.REMOVE));
		panelEvaluateReliability.add(btnRemoveMetricReliability);
		btnRemoveMetricReliability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int row = tblMetricsReliability.getSelectedRow();
				removeMetric(row, reliabilityMetrics);
				refreshTable(tblMetricsReliability, reliabilityMetrics,
						tableModelReliability);
				btnRemoveMetricReliability.setEnabled(false);
			}
		});
		
		clearTable(tblMetricsReliability, tableModelReliability);
		setKeyListener(txtValueMaturity, txtValueFaultTolerance,
				txtValueRecoverability);
		setFocusListener(lblTotalValueReliability, txtValueMaturity,
				txtValueFaultTolerance, txtValueRecoverability);

		return tabReliability;
	}

	private JPanel createTabUsability() {
		JPanel tabUsability = new JPanel();
		tabUsability.setLayout(null);
		
		JPanel panelValueUsability = new JPanel();
		panelValueUsability.setLayout(null);
		panelValueUsability.setBorder(new TitledBorder(null,
				"Valor por sub-caracter\u00EDstica (%)", TitledBorder.LEADING,
				TitledBorder.TOP, null, new Color(59, 59, 59)));
		panelValueUsability.setBounds(0, 6, 265, 270);
		tabUsability.add(panelValueUsability);
		
		txtValueLearnability = new JTextField();
		txtValueLearnability.setText("25.00");
		txtValueLearnability.setEditable(false);
		txtValueLearnability.setBounds(200, 55, 50, 25);
		panelValueUsability.add(txtValueLearnability);
		
		JLabel lblValueLearnability = new JLabel("Comprensabilidad:");
		lblValueLearnability.setBounds(60, 60, 128, 16);
		panelValueUsability.add(lblValueLearnability);
		
		JLabel lblValueOperability = new JLabel("Operabilidad:");
		lblValueOperability.setBounds(60, 90, 128, 16);
		panelValueUsability.add(lblValueOperability);
		
		txtValueOperability = new JTextField();
		txtValueOperability.setText("25.00");
		txtValueOperability.setEditable(false);
		txtValueOperability.setBounds(200, 83, 50, 25);
		panelValueUsability.add(txtValueOperability);
		
		JLabel lblValueAttractiveness = new JLabel("Atractividad:");
		lblValueAttractiveness.setBounds(60, 120, 128, 16);
		panelValueUsability.add(lblValueAttractiveness);
		
		txtValueAttractiveness = new JTextField();
		txtValueAttractiveness.setText("25.00");
		txtValueAttractiveness.setEditable(false);
		txtValueAttractiveness.setBounds(200, 111, 50, 25);
		panelValueUsability.add(txtValueAttractiveness);
		
		JLabel lblValueUnderstandability = new JLabel("Aprendibilidad:");
		lblValueUnderstandability.setBounds(60, 30, 128, 16);
		panelValueUsability.add(lblValueUnderstandability);
		
		txtValueUnderstandability = new JTextField();
		txtValueUnderstandability.setText("25.00");
		txtValueUnderstandability.setEditable(false);
		txtValueUnderstandability.setBounds(200, 27, 50, 25);
		panelValueUsability.add(txtValueUnderstandability);
		
		btnModifyValueUsability = new JButton();
		btnModifyValueUsability.setBounds(15, 25, 35, 35);
		btnModifyValueUsability.setToolTipText("Modificar");
		btnModifyValueUsability.setIcon(getIcon(IconEnum.MODIFY));
		panelValueUsability.add(btnModifyValueUsability);
		btnModifyValueUsability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnRestoreValueUsability.setEnabled(true);
				btnModifyValueUsability.setEnabled(false);
				modifyValueSubCharacteristics(true, "0",
						lblTotalValueUsability, "Total:     0",
						txtValueUnderstandability, txtValueLearnability,
						txtValueOperability, txtValueAttractiveness);
			}
		});
		
		btnRestoreValueUsability = new JButton();
		btnRestoreValueUsability.setEnabled(false);
		btnRestoreValueUsability.setFocusable(false);
		btnRestoreValueUsability.setBounds(15, 61, 35, 35);
		btnRestoreValueUsability.setToolTipText("Restablecer");
		btnRestoreValueUsability.setIcon(getIcon(IconEnum.RESTORE));
		panelValueUsability.add(btnRestoreValueUsability);
		btnRestoreValueUsability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnModifyValueUsability.requestFocus();
				btnModifyValueUsability.setEnabled(true);
				btnRestoreValueUsability.setEnabled(false);
				modifyValueSubCharacteristics(false, "25.00",
						lblTotalValueUsability, "Total:     100",
						txtValueUnderstandability, txtValueLearnability,
						txtValueOperability, txtValueAttractiveness);
			}
		});
		
		lblTotalValueUsability = new JLabel("Total:     100");
		lblTotalValueUsability.setFont(new Font("SansSerif", Font.BOLD, 12));
		lblTotalValueUsability.setBounds(180, 235, 70, 16);
		panelValueUsability.add(lblTotalValueUsability);
		
		JPanel panelEvaluateUsability = new JPanel();
		panelEvaluateUsability.setLayout(null);
		panelEvaluateUsability.setBounds(265, 6, 505, 270);
		panelEvaluateUsability.setBorder(new TitledBorder(null,
				"Evaluar m\u00E9tricas", TitledBorder.LEADING,
				TitledBorder.TOP, null, new Color(59, 59, 59)));
		tabUsability.add(panelEvaluateUsability);
				
		tblMetricsUsability = new JTable();
		tblMetricsUsability.setRowHeight(20);
		tblMetricsUsability.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		tblMetricsUsability.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				btnRemoveMetricUsability.setEnabled(true);
			}
		});
		
		JScrollPane spEvaluateUsability = new JScrollPane();
		spEvaluateUsability.setBounds(51, 25, 435, 225);
		spEvaluateUsability.setViewportView(tblMetricsUsability);
		panelEvaluateUsability.add(spEvaluateUsability);
		
		btnAddMetricUsability = new JButton();
		btnAddMetricUsability.setToolTipText("Agregar");
		btnAddMetricUsability.setBounds(15, 25, 35, 35);
		btnAddMetricUsability.setIcon(getIcon(IconEnum.ADD));
		panelEvaluateUsability.add(btnAddMetricUsability);
		btnAddMetricUsability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				addMetric(CharacteristicEnum.USABILITY,
						usabilityMetrics, tableModelUsability);
			}
		});
		
		btnRemoveMetricUsability = new JButton();
		btnRemoveMetricUsability.setEnabled(false);
		btnRemoveMetricUsability.setToolTipText("Quitar");
		btnRemoveMetricUsability.setBounds(15, 61, 35, 35);
		btnRemoveMetricUsability.setIcon(getIcon(IconEnum.REMOVE));
		panelEvaluateUsability.add(btnRemoveMetricUsability);
		btnRemoveMetricUsability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int row = tblMetricsReliability.getSelectedRow();
				removeMetric(row, usabilityMetrics);
				refreshTable(tblMetricsReliability, usabilityMetrics,
						tableModelUsability);
				btnRemoveMetricUsability.setEnabled(false);
			}
		});
		
		clearTable(tblMetricsUsability, tableModelUsability);
		setKeyListener(txtValueUnderstandability, txtValueLearnability,
				txtValueOperability, txtValueAttractiveness);
		setFocusListener(lblTotalValueUsability, txtValueUnderstandability,
				txtValueLearnability, txtValueOperability,
				txtValueAttractiveness);

		return tabUsability;
	}

	private JPanel createTabEfficiency() {
		JPanel tabEfficiency = new JPanel();
		tabEfficiency.setLayout(null);
		
		JPanel panelValueEfficiency = new JPanel();
		panelValueEfficiency.setLayout(null);
		panelValueEfficiency.setBounds(0, 6, 265, 270);
		panelValueEfficiency.setBorder(new TitledBorder(null,
				"Valor por sub-caracter\u00EDstica (%)", TitledBorder.LEADING,
				TitledBorder.TOP, null, new Color(59, 59, 59)));
		tabEfficiency.add(panelValueEfficiency);
				
		JLabel lblValueResourceUtilisation = new JLabel("Utilización de recursos:");
		lblValueResourceUtilisation.setBounds(60, 60, 135, 16);
		panelValueEfficiency.add(lblValueResourceUtilisation);
		
		txtValueResourceUtilisation = new JTextField();
		txtValueResourceUtilisation.setText("50.00");
		txtValueResourceUtilisation.setEditable(false);
		txtValueResourceUtilisation.setBounds(200, 55, 50, 25);
		panelValueEfficiency.add(txtValueResourceUtilisation);
		
		JLabel lblValueTimeBehaviour = new JLabel("Tiempo de respuesta:");
		lblValueTimeBehaviour.setBounds(60, 30, 128, 16);
		panelValueEfficiency.add(lblValueTimeBehaviour);
		
		txtValueTimeBehaviour = new JTextField();
		txtValueTimeBehaviour.setText("50.00");
		txtValueTimeBehaviour.setEditable(false);
		txtValueTimeBehaviour.setBounds(200, 27, 50, 25);
		panelValueEfficiency.add(txtValueTimeBehaviour);
		
		lblTotalValueEfficiency = new JLabel("Total:     100");
		lblTotalValueEfficiency.setBounds(180, 235, 70, 16);
		lblTotalValueEfficiency.setFont(new Font("SansSerif", Font.BOLD, 12));
		panelValueEfficiency.add(lblTotalValueEfficiency);
				
		btnModifyValueEfficiency = new JButton();
		btnModifyValueEfficiency.setBounds(15, 25, 35, 35);
		btnModifyValueEfficiency.setToolTipText("Modificar");
		btnModifyValueEfficiency.setIcon(getIcon(IconEnum.MODIFY));
		panelValueEfficiency.add(btnModifyValueEfficiency);
		btnModifyValueEfficiency.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnRestoreValueEfficiency.setEnabled(true);
				btnModifyValueEfficiency.setEnabled(false);
				modifyValueSubCharacteristics(true, "0",
						lblTotalValueEfficiency, "Total:     0",
						txtValueResourceUtilisation, txtValueTimeBehaviour);
			}
		});
		
		btnRestoreValueEfficiency = new JButton();
		btnRestoreValueEfficiency.setEnabled(false);
		btnRestoreValueEfficiency.setFocusable(false);
		btnRestoreValueEfficiency.setBounds(15, 61, 35, 35);
		btnRestoreValueEfficiency.setToolTipText("Restablecer");
		btnRestoreValueEfficiency.setIcon(getIcon(IconEnum.RESTORE));
		panelValueEfficiency.add(btnRestoreValueEfficiency);
		btnRestoreValueEfficiency.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnModifyValueEfficiency.requestFocus();
				btnModifyValueEfficiency.setEnabled(true);
				btnRestoreValueEfficiency.setEnabled(false);
				modifyValueSubCharacteristics(false, "50.00",
						lblTotalValueEfficiency, "Total:     100",
						txtValueResourceUtilisation, txtValueTimeBehaviour);
			}
		});		
		
		JPanel panelEvaluateEfficiency = new JPanel();
		panelEvaluateEfficiency.setLayout(null);
		panelEvaluateEfficiency.setBorder(new TitledBorder(null, "Evaluar m\u00E9tricas",
				TitledBorder.LEADING, TitledBorder.TOP, null, new Color(59, 59, 59)));
		panelEvaluateEfficiency.setBounds(265, 6, 505, 270);
		tabEfficiency.add(panelEvaluateEfficiency);
				
		tblMetricsEfficiency = new JTable();
		tblMetricsEfficiency.setRowHeight(20);
		tblMetricsEfficiency.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		tblMetricsEfficiency.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				btnRemoveMetricEfficiency.setEnabled(true);
			}
		});
		
		JScrollPane spEvaluateEfficiency = new JScrollPane();
		spEvaluateEfficiency.setBounds(51, 25, 435, 225);
		spEvaluateEfficiency.setViewportView(tblMetricsEfficiency);
		panelEvaluateEfficiency.add(spEvaluateEfficiency);
				
		btnAddMetricEfficiency = new JButton();
		btnAddMetricEfficiency.setBounds(15, 25, 35, 35);
		btnAddMetricEfficiency.setToolTipText("Agregar");
		btnAddMetricEfficiency.setIcon(getIcon(IconEnum.ADD));
		panelEvaluateEfficiency.add(btnAddMetricEfficiency);
		btnAddMetricEfficiency.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				addMetric(CharacteristicEnum.EFFICIENCY, efficiencyMetrics,
						tableModelEfficiency);
			}
		});
		
		btnRemoveMetricEfficiency = new JButton();
		btnRemoveMetricEfficiency.setEnabled(false);
		btnRemoveMetricEfficiency.setToolTipText("Quitar");
		btnRemoveMetricEfficiency.setBounds(15, 61, 35, 35);
		btnRemoveMetricEfficiency.setIcon(getIcon(IconEnum.REMOVE));
		panelEvaluateEfficiency.add(btnRemoveMetricEfficiency);
		btnRemoveMetricEfficiency.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int row = tblMetricsEfficiency.getSelectedRow();
				removeMetric(row, efficiencyMetrics);
				refreshTable(tblMetricsEfficiency, efficiencyMetrics,
						tableModelEfficiency);
				btnRemoveMetricEfficiency.setEnabled(false);
			}
		});
		
		clearTable(tblMetricsEfficiency, tableModelEfficiency);
		setKeyListener(txtValueTimeBehaviour, txtValueResourceUtilisation);
		setFocusListener(lblTotalValueEfficiency, txtValueResourceUtilisation,
				txtValueTimeBehaviour);	

		return tabEfficiency;
	}

	private JPanel createTabMaintainability() {
		JPanel tabMaintainability = new JPanel();
		tabMaintainability.setLayout(null);
		
		JPanel panelValueMaintainability = new JPanel();
		panelValueMaintainability.setLayout(null);
		panelValueMaintainability.setBorder(new TitledBorder(null,
				"Valor por sub-caracter\u00EDstica (%)", TitledBorder.LEADING,
				TitledBorder.TOP, null, new Color(59, 59, 59)));
		panelValueMaintainability.setBounds(0, 6, 265, 270);
		tabMaintainability.add(panelValueMaintainability);
		
		txtValueChangeability = new JTextField();
		txtValueChangeability.setText("25.00");
		txtValueChangeability.setEditable(false);
		txtValueChangeability.setBounds(200, 55, 50, 25);
		panelValueMaintainability.add(txtValueChangeability);
		
		JLabel lblValueChangeability = new JLabel("Facilidad de cambio:");
		lblValueChangeability.setBounds(60, 60, 128, 16);
		panelValueMaintainability.add(lblValueChangeability);
		
		JLabel lblValueStability = new JLabel("Estabilidad:");
		lblValueStability.setBounds(60, 90, 128, 16);
		panelValueMaintainability.add(lblValueStability);
		
		txtValueStability = new JTextField();
		txtValueStability.setText("25.00");
		txtValueStability.setEditable(false);
		txtValueStability.setBounds(200, 83, 50, 25);
		panelValueMaintainability.add(txtValueStability);
		
		JLabel lblValueTestability = new JLabel("Facilidad de prueba:");
		lblValueTestability.setBounds(60, 120, 128, 16);
		panelValueMaintainability.add(lblValueTestability);
		
		txtValueTestability = new JTextField();
		txtValueTestability.setText("25.00");
		txtValueTestability.setEditable(false);
		txtValueTestability.setBounds(200, 111, 50, 25);
		panelValueMaintainability.add(txtValueTestability);
		
		JLabel lblValueAnalyzability = new JLabel("Facilidad de análisis:");
		lblValueAnalyzability.setBounds(60, 30, 128, 16);
		panelValueMaintainability.add(lblValueAnalyzability);
		
		txtValueAnalyzability = new JTextField();
		txtValueAnalyzability.setText("25.00");
		txtValueAnalyzability.setEditable(false);
		txtValueAnalyzability.setBounds(200, 27, 50, 25);
		panelValueMaintainability.add(txtValueAnalyzability);
		
		btnModifyValueMaintainability = new JButton();
		btnModifyValueMaintainability.setBounds(15, 25, 35, 35);
		btnModifyValueMaintainability.setToolTipText("Modificar");
		btnModifyValueMaintainability.setIcon(getIcon(IconEnum.MODIFY));
		panelValueMaintainability.add(btnModifyValueMaintainability);
		btnModifyValueMaintainability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnRestoreValueMaintainability.setEnabled(true);
				btnModifyValueMaintainability.setEnabled(false);
				modifyValueSubCharacteristics(true, "0",
						lblTotalValueMaintainability, "Total:     0",
						txtValueAnalyzability, txtValueChangeability,
						txtValueStability, txtValueTestability);
			}
		});
		
		btnRestoreValueMaintainability = new JButton();
		btnRestoreValueMaintainability.setEnabled(false);
		btnRestoreValueMaintainability.setFocusable(false);
		btnRestoreValueMaintainability.setBounds(15, 61, 35, 35);
		btnRestoreValueMaintainability.setToolTipText("Restablecer");
		btnRestoreValueMaintainability.setIcon(getIcon(IconEnum.RESTORE));
		btnRestoreValueMaintainability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnModifyValueMaintainability.requestFocus();
				btnModifyValueMaintainability.setEnabled(true);
				btnRestoreValueMaintainability.setEnabled(false);
				modifyValueSubCharacteristics(false, "25.00",
						lblTotalValueMaintainability, "Total:     100",
						txtValueAnalyzability, txtValueChangeability,
						txtValueStability, txtValueTestability);
			}
		});
		panelValueMaintainability.add(btnRestoreValueMaintainability);
		
		lblTotalValueMaintainability = new JLabel("Total:     100");
		lblTotalValueMaintainability.setBounds(180, 235, 70, 16);
		lblTotalValueMaintainability.setFont(new Font("SansSerif", Font.BOLD, 12));
		panelValueMaintainability.add(lblTotalValueMaintainability);
		
		JPanel panelEvaluateMaintainability = new JPanel();
		panelEvaluateMaintainability.setLayout(null);
		panelEvaluateMaintainability.setBounds(265, 6, 505, 270);
		panelEvaluateMaintainability.setBorder(new TitledBorder(null,
				"Evaluar m\u00E9tricas", TitledBorder.LEADING,
				TitledBorder.TOP, null, new Color(59, 59, 59)));
		tabMaintainability.add(panelEvaluateMaintainability);
				
		tblMetricsMaintainability = new JTable();
		tblMetricsMaintainability.setRowHeight(20);
		tblMetricsMaintainability.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		tblMetricsMaintainability.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				btnRemoveMetricMaintainability.setEnabled(true);
			}
		});
		
		JScrollPane spEvaluateMaintainability = new JScrollPane();
		spEvaluateMaintainability.setBounds(51, 25, 435, 225);
		spEvaluateMaintainability.setViewportView(tblMetricsMaintainability);
		panelEvaluateMaintainability.add(spEvaluateMaintainability);

		btnAddMetricMaintainability = new JButton();
		btnAddMetricMaintainability.setBounds(15, 25, 35, 35);
		btnAddMetricMaintainability.setToolTipText("Agregar");
		btnAddMetricMaintainability.setIcon(getIcon(IconEnum.ADD));
		panelEvaluateMaintainability.add(btnAddMetricMaintainability);
		btnAddMetricMaintainability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				addMetric(CharacteristicEnum.MAINTAINABILITY,
						maintainabilityMetrics, tableModelMaintainability);
			}
		});
		
		btnRemoveMetricMaintainability = new JButton();
		btnRemoveMetricMaintainability.setEnabled(false);
		btnRemoveMetricMaintainability.setToolTipText("Quitar");
		btnRemoveMetricMaintainability.setBounds(15, 61, 35, 35);
		btnRemoveMetricMaintainability.setIcon(getIcon(IconEnum.REMOVE));
		panelEvaluateMaintainability.add(btnRemoveMetricMaintainability);
		btnRemoveMetricMaintainability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int row = tblMetricsMaintainability.getSelectedRow();
				removeMetric(row, maintainabilityMetrics);
				refreshTable(tblMetricsMaintainability, maintainabilityMetrics,
						tableModelMaintainability);
				btnRemoveMetricMaintainability.setEnabled(false);
			}
		});
		
		clearTable(tblMetricsMaintainability, tableModelMaintainability);
		setKeyListener(txtValueAnalyzability, txtValueChangeability,
				txtValueStability, txtValueTestability);
		setFocusListener(lblTotalValueMaintainability, txtValueAnalyzability,
				txtValueChangeability, txtValueStability, txtValueTestability);

		return tabMaintainability;
	}

	private JPanel createTabPortability() {
		JPanel tabPortability = new JPanel();
		tabPortability.setLayout(null);
		
		JPanel panelValuePortability = new JPanel();
		panelValuePortability.setLayout(null);
		panelValuePortability.setBorder(new TitledBorder(null,
				"Valor por sub-caracter\u00EDstica (%)", TitledBorder.LEADING,
				TitledBorder.TOP, null, new Color(59, 59, 59)));
		panelValuePortability.setBounds(0, 6, 265, 270);
		tabPortability.add(panelValuePortability);
		
		txtValueInstallability = new JTextField();
		txtValueInstallability.setText("25.00");
		txtValueInstallability.setEditable(false);
		txtValueInstallability.setBounds(200, 55, 50, 25);
		panelValuePortability.add(txtValueInstallability);
		
		JLabel lblValueInstallability = new JLabel("Instalabilidad:");
		lblValueInstallability.setBounds(60, 60, 128, 16);
		panelValuePortability.add(lblValueInstallability);
		
		JLabel lblValueCoExistence = new JLabel("Co-Existencia:");
		lblValueCoExistence.setBounds(60, 90, 128, 16);
		panelValuePortability.add(lblValueCoExistence);
		
		txtValueCoExistence = new JTextField();
		txtValueCoExistence.setText("25.00");
		txtValueCoExistence.setEditable(false);
		txtValueCoExistence.setBounds(200, 83, 50, 25);
		panelValuePortability.add(txtValueCoExistence);
		
		JLabel lblValueReplaceability = new JLabel("Reemplazabilidad:");
		lblValueReplaceability.setBounds(60, 120, 128, 16);
		panelValuePortability.add(lblValueReplaceability);
		
		txtValueReplaceability = new JTextField();
		txtValueReplaceability.setText("25.00");
		txtValueReplaceability.setEditable(false);
		txtValueReplaceability.setBounds(200, 111, 50, 25);
		panelValuePortability.add(txtValueReplaceability);
		
		JLabel lblValueAdaptability = new JLabel("Adaptabilidad:");
		lblValueAdaptability.setBounds(60, 30, 128, 16);
		panelValuePortability.add(lblValueAdaptability);
		
		txtValueAdaptability = new JTextField();
		txtValueAdaptability.setText("25.00");
		txtValueAdaptability.setEditable(false);
		txtValueAdaptability.setBounds(200, 27, 50, 25);
		panelValuePortability.add(txtValueAdaptability);
		
		btnModifyValuePortability = new JButton();
		btnModifyValuePortability.setBounds(15, 25, 35, 35);
		btnModifyValuePortability.setToolTipText("Modificar");
		btnModifyValuePortability.setIcon(getIcon(IconEnum.MODIFY));
		panelValuePortability.add(btnModifyValuePortability);
		btnModifyValuePortability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnRestoreValuePortability.setEnabled(true);
				btnModifyValuePortability.setEnabled(false);
				modifyValueSubCharacteristics(true, "0",
						lblTotalValuePortability, "Total:     0",
						txtValueAdaptability, txtValueInstallability,
						txtValueCoExistence, txtValueReplaceability);
			}
		});
		
		btnRestoreValuePortability = new JButton();
		btnRestoreValuePortability.setEnabled(false);
		btnRestoreValuePortability.setFocusable(false);
		btnRestoreValuePortability.setToolTipText("Restore");
		btnRestoreValuePortability.setBounds(15, 61, 35, 35);
		btnRestoreValuePortability.setIcon(getIcon(IconEnum.RESTORE));
		panelValuePortability.add(btnRestoreValuePortability);
		btnRestoreValuePortability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnModifyValuePortability.requestFocus();
				btnModifyValuePortability.setEnabled(true);
				btnRestoreValuePortability.setEnabled(false);
				modifyValueSubCharacteristics(false, "25.00",
						lblTotalValuePortability, "Total:     100",
						txtValueAdaptability, txtValueInstallability,
						txtValueCoExistence, txtValueReplaceability);
			}
		});
		
		lblTotalValuePortability = new JLabel("Total:     100");
		lblTotalValuePortability.setBounds(180, 235, 70, 16);
		lblTotalValuePortability.setFont(new Font("SansSerif", Font.BOLD, 12));
		panelValuePortability.add(lblTotalValuePortability);
		
		JPanel panelEvaluatePortability = new JPanel();
		panelEvaluatePortability.setLayout(null);
		panelEvaluatePortability.setBounds(265, 6, 505, 270);
		panelEvaluatePortability.setBorder(new TitledBorder(null,
				"Evaluar m\u00E9tricas", TitledBorder.LEADING,
				TitledBorder.TOP, null, new Color(59, 59, 59)));
		tabPortability.add(panelEvaluatePortability);
				
		tblMetricsPortability = new JTable();
		tblMetricsPortability.setRowHeight(20);
		tblMetricsPortability.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		tblMetricsPortability.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				btnRemoveMetricPortability.setEnabled(true);
			}
		});
		
		JScrollPane spEvaluatePortability = new JScrollPane();
		spEvaluatePortability.setBounds(51, 25, 435, 225);
		spEvaluatePortability.setViewportView(tblMetricsPortability);
		panelEvaluatePortability.add(spEvaluatePortability);

		btnAddMetricPortability = new JButton();
		btnAddMetricPortability.setToolTipText("Agregar");
		btnAddMetricPortability.setBounds(15, 25, 35, 35);
		btnAddMetricPortability.setIcon(getIcon(IconEnum.ADD));
		panelEvaluatePortability.add(btnAddMetricPortability);
		btnAddMetricPortability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				addMetric(CharacteristicEnum.PORTABILITY,
						portabilityMetrics, tableModelPortability);
			}
		});
		
		btnRemoveMetricPortability = new JButton();
		btnRemoveMetricPortability.setEnabled(false);
		btnRemoveMetricPortability.setToolTipText("Quitar");
		btnRemoveMetricPortability.setBounds(15, 61, 35, 35);
		btnRemoveMetricPortability.setIcon(getIcon(IconEnum.REMOVE));
		panelEvaluatePortability.add(btnRemoveMetricPortability);
		btnRemoveMetricPortability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int row = tblMetricsPortability.getSelectedRow();
				removeMetric(row, portabilityMetrics);
				refreshTable(tblMetricsPortability, portabilityMetrics,
						tableModelPortability);
				btnRemoveMetricPortability.setEnabled(false);
			}
		});
		
		clearTable(tblMetricsPortability, tableModelPortability);
		setKeyListener(txtValueAdaptability, txtValueInstallability,
				txtValueCoExistence, txtValueReplaceability);
		setFocusListener(lblTotalValuePortability, txtValueAdaptability,
				txtValueInstallability, txtValueCoExistence, txtValueReplaceability);

		return tabPortability;
	}
	
	private void createValueFunctionality(JPanel panelValueChrtcs,
			int[] coordinate) {
		JLabel lblValueFunctionality = new JLabel("Funcionalidad:");
		lblValueFunctionality.setBounds(coordinate[0], coordinate[1],
				LABEL_WIDTH, LABEL_HEIGHT);
		panelValueChrtcs.add(lblValueFunctionality);

		txtValueFunctionality = new JTextField();
		txtValueFunctionality.setEditable(false);
		txtValueFunctionality.setBounds(coordinate[0] + LABEL_WIDTH + 5,
				coordinate[1] - 5, 50, 25);
		txtValueFunctionality.setText(characteristics
				.get(CharacteristicEnum.FUNCTIONALITY).getWeight().toString());
		setKeyListener(txtValueFunctionality);
		setFocusListener(txtValueFunctionality);
		panelValueChrtcs.add(txtValueFunctionality);
	}
	
	private void createValueEfficiency(JPanel panelValueChrtcs, int[] coordinate) {
		JLabel lblValueEfficiency = new JLabel("Eficiencia:");
		lblValueEfficiency.setBounds(coordinate[0], coordinate[1], LABEL_WIDTH,
				LABEL_HEIGHT);
		panelValueChrtcs.add(lblValueEfficiency);

		txtValueEfficiency = new JTextField();
		txtValueEfficiency.setEditable(false);
		txtValueEfficiency.setBounds(coordinate[0] + LABEL_WIDTH + 5,
				coordinate[1] - 5, 50, 25);
		txtValueEfficiency.setText(characteristics
				.get(CharacteristicEnum.EFFICIENCY).getWeight().toString());
		setKeyListener(txtValueEfficiency);
		setFocusListener(txtValueEfficiency);
		panelValueChrtcs.add(txtValueEfficiency);
	}

	private void createValueMaintainability(JPanel panelValueChrtcs,
			int[] coordinate) {
		JLabel lblValueMaintainability = new JLabel("Mantenibilidad:");
		lblValueMaintainability.setBounds(coordinate[0], coordinate[1],
				LABEL_WIDTH, LABEL_HEIGHT);
		panelValueChrtcs.add(lblValueMaintainability);

		txtValueMaintainability = new JTextField();
		txtValueMaintainability.setEditable(false);
		txtValueMaintainability.setBounds(coordinate[0] + LABEL_WIDTH + 5,
				coordinate[1] - 5, 50, 25);
		txtValueMaintainability.setText(characteristics
				.get(CharacteristicEnum.MAINTAINABILITY).getWeight().toString());
		setKeyListener(txtValueMaintainability);
		setFocusListener(txtValueMaintainability);
		panelValueChrtcs.add(txtValueMaintainability);
	}

	private void createValueReliability(JPanel panelValueChrtcs,
			int[] coordinate) {
		JLabel lblValueReliability = new JLabel("Fiabilidad:");
		lblValueReliability.setBounds(coordinate[0], coordinate[1],
				LABEL_WIDTH, LABEL_HEIGHT);
		panelValueChrtcs.add(lblValueReliability);

		txtValueReliability = new JTextField();
		txtValueReliability.setEditable(false);
		txtValueReliability.setBounds(coordinate[0] + LABEL_WIDTH + 5,
				coordinate[1] - 5, 50, 25);
		txtValueReliability.setText(characteristics
				.get(CharacteristicEnum.RELIABILITY).getWeight().toString());
		setKeyListener(txtValueReliability);
		setFocusListener(txtValueReliability);
		panelValueChrtcs.add(txtValueReliability);
	}

	private void createValueUsability(JPanel panelValueChrtcs, int[] coordinate) {
		JLabel lblValueUsability = new JLabel("Usabilidad:");
		lblValueUsability.setBounds(coordinate[0], coordinate[1], LABEL_WIDTH,
				LABEL_HEIGHT);
		panelValueChrtcs.add(lblValueUsability);

		txtValueUsability = new JTextField();
		txtValueUsability.setEditable(false);
		txtValueUsability.setBounds(coordinate[0] + LABEL_WIDTH + 5,
				coordinate[1] - 5, 50, 25);
		txtValueUsability.setText(characteristics.get(CharacteristicEnum.USABILITY)
				.getWeight().toString());
		setKeyListener(txtValueUsability);
		setFocusListener(txtValueUsability);
		panelValueChrtcs.add(txtValueUsability);
	}

	private void createValuePortability(JPanel panelValueChrtcs,
			int[] coordinate) {
		JLabel lblValuePortability = new JLabel("Portabilidad:");
		lblValuePortability.setBounds(coordinate[0], coordinate[1],
				LABEL_WIDTH, LABEL_HEIGHT);
		panelValueChrtcs.add(lblValuePortability);

		txtValuePortability = new JTextField();
		txtValuePortability.setEditable(false);
		txtValuePortability.setBounds(coordinate[0] + LABEL_WIDTH + 5,
				coordinate[1] - 5, 50, 25);
		txtValuePortability.setText(characteristics
				.get(CharacteristicEnum.PORTABILITY).getWeight().toString());
		setKeyListener(txtValuePortability);
		setFocusListener(txtValuePortability);
		panelValueChrtcs.add(txtValuePortability);
	}
	
	private void setFocusListener(final JTextField textField) {
		textField.addFocusListener(new FocusListener() {
			public void focusLost(FocusEvent e) {
				if (textField.isEditable()) {
					if (textField.getText().isEmpty()) {
						textField.setText("0");
					}
					
					lblTotalValueChrtcs.setText("Total:     "
							+ addValueCharacteristics().intValue());					
				}
			}

			public void focusGained(FocusEvent e) {
				if (textField.isEditable()) {
					textField.selectAll();					
				}
			}
		});
	}
	
	private void setFocusListener(final JLabel lblTotalValue,
			final JTextField... txtFields) {
		for (final JTextField txtField : txtFields) {
			txtField.addFocusListener(new FocusListener() {
				public void focusLost(FocusEvent e) {
					if (txtField.isEditable()) {
						if (txtField.getText().isEmpty()) {
							txtField.setText("0");
						}
						
						lblTotalValue.setText("Total:     "
								+ addValueSubCharacteristics(txtFields).intValue());						
					}
				}

				public void focusGained(FocusEvent e) {
					if (txtField.isEditable()) {
						txtField.selectAll();						
					}
				}
			});
		}
	}	
	
	private void setKeyListener(JTextField... textFields) {
		for (final JTextField textField : textFields) {
			textField.addKeyListener(new KeyAdapter() {
				public void keyTyped(KeyEvent e) {
					char character = e.getKeyChar();
					String text = getText(textField);

					if (percentFieldValidator(character, text)) {
						e.consume();
					}
				}
			});
		}
	}	
		
	private void callSelectorMetric(ActionEnum action,
			CharacteristicEnum characteristic) {
		ManageMetrics manageMetrics = new ManageMetrics(this, action,
				characteristic);
		manageMetrics.setVisible(true);
	}
	
	private void callEvaluationModal(ProductEvaluated productEvaluated) {
		EvaluationModal evaluationModal = new EvaluationModal(this, productEvaluated);
		evaluationModal.setVisible(true);
	}
		
	private void closeWindow() {
		int option = JOptionPane.showConfirmDialog(this,
				"Está seguro de cerrar la evaluación",
				"Mensaje de confirmación", JOptionPane.YES_NO_OPTION);

		if (JOptionPane.YES_OPTION == option) {
			dispose();
		}
	}
	
	@SuppressWarnings("serial")
	private DefaultTableModel createTableModel() {
		DefaultTableModel tableModel = new DefaultTableModel(null,
				new String[] { "M\u00E9trica", "Sub-caracter\u00EDstica",
						"Evaluación" }) {
			Class<?>[] columnTypes = new Class[] { String.class, String.class,
					String.class };

			public Class<?> getColumnClass(int columnIndex) {
				return columnTypes[columnIndex];
			}

			boolean[] columnEditables = new boolean[] { true, false, true };

			public boolean isCellEditable(int row, int column) {
				return columnEditables[column];
			}
		};

		return tableModel;
	}
	
	private void clearTable(JTable table, DefaultTableModel tableModel) {
		tableModel.setDataVector(null, new String[] { "M\u00E9trica",
				"Sub-caracter\u00EDstica", "Evaluación" });

		table.setModel(tableModel);
		table.getColumnModel().getColumn(0).setResizable(false);
		table.getColumnModel().getColumn(0).setPreferredWidth(155);
		table.getColumnModel().getColumn(1).setResizable(false);
		table.getColumnModel().getColumn(1).setPreferredWidth(90);
		table.getColumnModel().getColumn(2).setResizable(false);
		table.getColumnModel().getColumn(2).setPreferredWidth(30);
		
		DefaultCellEditor defaultCellEditor = new DefaultCellEditor(cbScales);
		table.getColumnModel().getColumn(2).setCellEditor(defaultCellEditor);
	}
	
	private boolean validateEvaluation() {	
		List<String> messages = new ArrayList<String>();
		
		if (validateValueCharacteristics()) {
			int totalValueChrtcs = addValueCharacteristics().intValue();
			
			if (totalValueChrtcs != 100) {
				messages.add("- El valor total por característica debe sumar el 100%");
			}			
		} else {
			messages.add("- El valor por característica no puede ser el 0%");
		}
		
		if (characteristics.containsKey(CharacteristicEnum.FUNCTIONALITY)) {
			validateCharacteristic(CharacteristicEnum.FUNCTIONALITY,
					functionalityMetrics, messages, tableModelFunctionality,
					txtValueSuitability, txtValueAccuracy,
					txtValueInteroperability, txtValueSecurity);
		}
			
		if (characteristics.containsKey(CharacteristicEnum.RELIABILITY)) {
			validateCharacteristic(CharacteristicEnum.RELIABILITY,
					reliabilityMetrics, messages, tableModelReliability,
					txtValueMaturity, txtValueFaultTolerance,
					txtValueRecoverability);
		}

		if (characteristics.containsKey(CharacteristicEnum.USABILITY)) {
			validateCharacteristic(CharacteristicEnum.USABILITY,
					usabilityMetrics, messages, tableModelUsability,
					txtValueUnderstandability, txtValueLearnability,
					txtValueOperability, txtValueAttractiveness);
		}

		if (characteristics.containsKey(CharacteristicEnum.EFFICIENCY)) {
			validateCharacteristic(CharacteristicEnum.EFFICIENCY,
					efficiencyMetrics, messages, tableModelEfficiency,
					txtValueTimeBehaviour, txtValueResourceUtilisation);
		}

		if (characteristics.containsKey(CharacteristicEnum.MAINTAINABILITY)) {
			validateCharacteristic(CharacteristicEnum.MAINTAINABILITY,
					maintainabilityMetrics, messages,
					tableModelMaintainability, txtValueAnalyzability,
					txtValueChangeability, txtValueStability,
					txtValueTestability);
		}

		if (characteristics.containsKey(CharacteristicEnum.PORTABILITY)) {
			validateCharacteristic(CharacteristicEnum.PORTABILITY,
					portabilityMetrics, messages, tableModelPortability,
					txtValueAdaptability, txtValueInstallability,
					txtValueCoExistence, txtValueReplaceability);
		}	
		
		if (!messages.isEmpty()) {
			StringBuilder finalMessage = new StringBuilder();
			messages.add(0, "Se presentaron los siguientes errores durante la validación: \n");

			for (String message : messages) {
				finalMessage.append(message);
				finalMessage.append('\n');
			}
			
			JOptionPane.showMessageDialog(this, finalMessage.toString(),
					"Mensaje de error", JOptionPane.ERROR_MESSAGE);
			return false;
		}
		
		return true;
	}
	
	private boolean validateValueCharacteristics() {
		if (characteristics.containsKey(CharacteristicEnum.FUNCTIONALITY)
				&& txtValueFunctionality.getText().equals("0")) {
			return false;
		}

		if (characteristics.containsKey(CharacteristicEnum.RELIABILITY)
				&& txtValueReliability.getText().equals("0")) {
			return false;
		}

		if (characteristics.containsKey(CharacteristicEnum.USABILITY)
				&& txtValueUsability.getText().equals("0")) {
			return false;
		}

		if (characteristics.containsKey(CharacteristicEnum.EFFICIENCY)
				&& txtValueEfficiency.getText().equals("0")) {
			return false;
		}

		if (characteristics.containsKey(CharacteristicEnum.MAINTAINABILITY)
				&& txtValueMaintainability.getText().equals("0")) {
			return false;
		}

		if (characteristics.containsKey(CharacteristicEnum.PORTABILITY)
				&& txtValuePortability.getText().equals("0")) {
			return false;
		}

		return true;
	}
	
	private boolean validateValueSubCharacteristics(JTextField... textFields) {
		for (JTextField textField : textFields) {
			if (textField.getText().equals("0")) {
				return false;
			}
		}

		return true;
	}
	
	private boolean validateEvaluationMetrics(DefaultTableModel tableModel) {
		for (int row = 0; row < tableModel.getRowCount(); row++) {
			final int column = 2;
			ScaleEnum scale = (ScaleEnum) tableModel.getValueAt(row, column);

			if (scale == ScaleEnum.NOT_SELECTED) {
				return false;
			}
		}

		return true;
	}
	
	private void assignEvaluationMetric(List<Metric> metrics,
			DefaultTableModel tableModel) {
		for (int row = 0; row < tableModel.getRowCount(); row++) {
			final int column = 2;
			ScaleEnum scale = (ScaleEnum) tableModel.getValueAt(row, column);
			metrics.get(row).setScale(scale);
		}
	}
	
	private void validateCharacteristic(CharacteristicEnum chrtc,
			List<Metric> metricsChrtc, List<String> messages,
			DefaultTableModel tableModel, JTextField... textFields) {
		if (!validateValueSubCharacteristics(textFields)) {
			messages.add("- " + chrtc + ": El valor por sub-característica no puede ser el 0%");
			return;
		}
		
		if (addValueSubCharacteristics(textFields).intValue() == 100) {
			if (!metricsChrtc.isEmpty()) {				
				List<SubCharacteristicEnum> subChrtcs = SubCharacteristicEnum
						.getByIdCharacteristic(chrtc.getId());
				
				boolean added = false;
				for (SubCharacteristicEnum subChrtc : subChrtcs) {
					for (Metric metric : metricsChrtc) {
						if (metric.getSubCharacteristicEnum() == subChrtc) {
							added = true;
							break;
						}
					}
					
					if (!added) {
						messages.add("- " + chrtc + ": No se ha agregado al menos una métrica por sub-característica");
						return;
					}
					
					added = false;
				}
			} else {
				messages.add("- " + chrtc + ": No se han agregado métricas a evaluar");
			}
		} else {
			messages.add("- " + chrtc + ": El valor total por sub-características debe ser el 100%");
		}
		
		if (!validateEvaluationMetrics(tableModel)) {
			messages.add("- " + chrtc + ": No se han evaluado todas las métricas");
			return;
		}
	}
	
	private void evaluate() {
		if (validateEvaluation()) {
			prepareEvaluation();
			
			Evaluator evaluator = new Evaluator();
			ProductEvaluated productEvaluated = evaluator.evaluateProduct(characteristics);
			callEvaluationModal(productEvaluated);
		}
	}
	
	private void prepareEvaluation() {	
		if (characteristics.containsKey(CharacteristicEnum.FUNCTIONALITY)) {
			prepareEvaluationFunctionality();
		}
		
		if (characteristics.containsKey(CharacteristicEnum.RELIABILITY)) {
			prepareEvaluationReliability();
		}

		if (characteristics.containsKey(CharacteristicEnum.USABILITY)) {
			prepareEvaluationUsability();
		}

		if (characteristics.containsKey(CharacteristicEnum.EFFICIENCY)) {
			prepareEvaluationEfficiency();
		}

		if (characteristics.containsKey(CharacteristicEnum.MAINTAINABILITY)) {
			prepareEvaluationMaintainability();			
		}

		if (characteristics.containsKey(CharacteristicEnum.PORTABILITY)) {
			prepareEvaluationPortability();			
		}
	}
	
	private void prepareEvaluationFunctionality() {
		Map<SubCharacteristicEnum, SubCharacteristic> subChrtcsFunctionality = new HashMap<SubCharacteristicEnum, SubCharacteristic>();
			
		SubCharacteristic suitability = new SubCharacteristic();
		suitability.setSubCharacteristicEnum(SubCharacteristicEnum.SUITABILITY);
		suitability.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueSuitability))));
		suitability.setMetrics(getMetricsBySubChrtc(functionalityMetrics, SubCharacteristicEnum.SUITABILITY));
			
		SubCharacteristic accuracy = new SubCharacteristic();
		accuracy.setSubCharacteristicEnum(SubCharacteristicEnum.ACCURACY);
		accuracy.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueAccuracy))));
		accuracy.setMetrics(getMetricsBySubChrtc(functionalityMetrics, SubCharacteristicEnum.ACCURACY));
			
		SubCharacteristic interoperability = new SubCharacteristic();
		interoperability.setSubCharacteristicEnum(SubCharacteristicEnum.INTEROPERABILITY);
		interoperability.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueInteroperability))));
		interoperability.setMetrics(getMetricsBySubChrtc(functionalityMetrics, SubCharacteristicEnum.INTEROPERABILITY));

		SubCharacteristic security = new SubCharacteristic();
		security.setSubCharacteristicEnum(SubCharacteristicEnum.SECURITY);
		security.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueSecurity))));
		security.setMetrics(getMetricsBySubChrtc(functionalityMetrics, SubCharacteristicEnum.SECURITY));
			
		subChrtcsFunctionality.put(SubCharacteristicEnum.SUITABILITY, suitability);
		subChrtcsFunctionality.put(SubCharacteristicEnum.ACCURACY, accuracy);
		subChrtcsFunctionality.put(SubCharacteristicEnum.INTEROPERABILITY, interoperability);
		subChrtcsFunctionality.put(SubCharacteristicEnum.SECURITY, security);
			
		assignEvaluationMetric(functionalityMetrics, tableModelFunctionality);
		
		Characteristic functionality = characteristics.get(CharacteristicEnum.FUNCTIONALITY);
		functionality.setSubcharacteristics(subChrtcsFunctionality);
		functionality.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueFunctionality))));
	}
	
	private void prepareEvaluationReliability() {
		Map<SubCharacteristicEnum, SubCharacteristic> subChrtcsReliability = new HashMap<SubCharacteristicEnum, SubCharacteristic>();
			
		SubCharacteristic maturity = new SubCharacteristic();
		maturity.setSubCharacteristicEnum(SubCharacteristicEnum.MATURITY);
		maturity.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueMaturity))));
		maturity.setMetrics(getMetricsBySubChrtc(reliabilityMetrics, SubCharacteristicEnum.MATURITY));
			
		SubCharacteristic faultTolerance = new SubCharacteristic();
		faultTolerance.setSubCharacteristicEnum(SubCharacteristicEnum.FAULT_TOLERANCE);
		faultTolerance.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueFaultTolerance))));
		faultTolerance.setMetrics(getMetricsBySubChrtc(reliabilityMetrics, SubCharacteristicEnum.FAULT_TOLERANCE));
			
		SubCharacteristic recoverability = new SubCharacteristic();
		recoverability.setSubCharacteristicEnum(SubCharacteristicEnum.RECOVERABILITY);
		recoverability.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueRecoverability))));
		recoverability.setMetrics(getMetricsBySubChrtc(reliabilityMetrics, SubCharacteristicEnum.RECOVERABILITY));
			
		subChrtcsReliability.put(SubCharacteristicEnum.MATURITY, maturity);
		subChrtcsReliability.put(SubCharacteristicEnum.FAULT_TOLERANCE, faultTolerance);
		subChrtcsReliability.put(SubCharacteristicEnum.INTEROPERABILITY, recoverability);
		
		assignEvaluationMetric(reliabilityMetrics, tableModelReliability);
			
		Characteristic reliability = characteristics.get(CharacteristicEnum.RELIABILITY);
		reliability.setSubcharacteristics(subChrtcsReliability);
		reliability.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueReliability))));	
	}
	
	private void prepareEvaluationUsability() {
		Map<SubCharacteristicEnum, SubCharacteristic> subChrtcsUsability = new HashMap<SubCharacteristicEnum, SubCharacteristic>();
			
		SubCharacteristic understandability = new SubCharacteristic();
		understandability.setSubCharacteristicEnum(SubCharacteristicEnum.UNDERSTANDABILITY);
		understandability.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueUnderstandability))));
		understandability.setMetrics(getMetricsBySubChrtc(usabilityMetrics, SubCharacteristicEnum.UNDERSTANDABILITY));
			
		SubCharacteristic learnability = new SubCharacteristic();
		learnability.setSubCharacteristicEnum(SubCharacteristicEnum.LEARNABILITY);
		learnability.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueLearnability))));
		learnability.setMetrics(getMetricsBySubChrtc(usabilityMetrics, SubCharacteristicEnum.LEARNABILITY));
			
		SubCharacteristic operability = new SubCharacteristic();
		operability.setSubCharacteristicEnum(SubCharacteristicEnum.OPERABILITY);
		operability.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueOperability))));
		operability.setMetrics(getMetricsBySubChrtc(usabilityMetrics, SubCharacteristicEnum.OPERABILITY));

		SubCharacteristic attractiveness = new SubCharacteristic();
		attractiveness.setSubCharacteristicEnum(SubCharacteristicEnum.ATTRACTIVENESS);
		attractiveness.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueAttractiveness))));
		attractiveness.setMetrics(getMetricsBySubChrtc(usabilityMetrics, SubCharacteristicEnum.ATTRACTIVENESS));
			
		subChrtcsUsability.put(SubCharacteristicEnum.UNDERSTANDABILITY, understandability);
		subChrtcsUsability.put(SubCharacteristicEnum.LEARNABILITY, learnability);
		subChrtcsUsability.put(SubCharacteristicEnum.OPERABILITY, operability);
		subChrtcsUsability.put(SubCharacteristicEnum.ATTRACTIVENESS, attractiveness);
		
		assignEvaluationMetric(usabilityMetrics, tableModelUsability);
			
		Characteristic usability = characteristics.get(CharacteristicEnum.USABILITY);
		usability.setSubcharacteristics(subChrtcsUsability);
		usability.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueUsability))));		
	}
	
	private void prepareEvaluationEfficiency() {
		Map<SubCharacteristicEnum, SubCharacteristic> subChrtcsEfficiency = new HashMap<SubCharacteristicEnum, SubCharacteristic>();
			
		SubCharacteristic timeBehaviour = new SubCharacteristic();
		timeBehaviour.setSubCharacteristicEnum(SubCharacteristicEnum.TIME_BEHAVIOUR);
		timeBehaviour.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueTimeBehaviour))));
		timeBehaviour.setMetrics(getMetricsBySubChrtc(efficiencyMetrics, SubCharacteristicEnum.TIME_BEHAVIOUR));
			
		SubCharacteristic resourceUtilisation = new SubCharacteristic();
		resourceUtilisation.setSubCharacteristicEnum(SubCharacteristicEnum.RESOURCE_UTILISATION);
		resourceUtilisation.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueResourceUtilisation))));
		resourceUtilisation.setMetrics(getMetricsBySubChrtc(efficiencyMetrics, SubCharacteristicEnum.RESOURCE_UTILISATION));
			
		subChrtcsEfficiency.put(SubCharacteristicEnum.TIME_BEHAVIOUR, timeBehaviour);
		subChrtcsEfficiency.put(SubCharacteristicEnum.RESOURCE_UTILISATION, resourceUtilisation);
		
		assignEvaluationMetric(efficiencyMetrics, tableModelEfficiency);
			
		Characteristic efficiency = characteristics.get(CharacteristicEnum.EFFICIENCY);
		efficiency.setSubcharacteristics(subChrtcsEfficiency);
		efficiency.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueEfficiency))));		
	}
	
	private void prepareEvaluationMaintainability() {
		Map<SubCharacteristicEnum, SubCharacteristic> subChrtcsMaintainability = new HashMap<SubCharacteristicEnum, SubCharacteristic>();
			
		SubCharacteristic analyzability = new SubCharacteristic();
		analyzability.setSubCharacteristicEnum(SubCharacteristicEnum.ANALYZABILITY);
		analyzability.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueAnalyzability))));
		analyzability.setMetrics(getMetricsBySubChrtc(maintainabilityMetrics, SubCharacteristicEnum.ANALYZABILITY));
			
		SubCharacteristic changeability = new SubCharacteristic();
		changeability.setSubCharacteristicEnum(SubCharacteristicEnum.CHANGEABILITY);
		changeability.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueChangeability))));
		changeability.setMetrics(getMetricsBySubChrtc(maintainabilityMetrics, SubCharacteristicEnum.CHANGEABILITY));
			
		SubCharacteristic stability = new SubCharacteristic();
		stability.setSubCharacteristicEnum(SubCharacteristicEnum.STABILITY);
		stability.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueStability))));
		stability.setMetrics(getMetricsBySubChrtc(maintainabilityMetrics, SubCharacteristicEnum.STABILITY));

		SubCharacteristic testability = new SubCharacteristic();
		testability.setSubCharacteristicEnum(SubCharacteristicEnum.TESTABILITY);
		testability.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueTestability))));
		testability.setMetrics(getMetricsBySubChrtc(maintainabilityMetrics, SubCharacteristicEnum.TESTABILITY));
			
		subChrtcsMaintainability.put(SubCharacteristicEnum.ANALYZABILITY, analyzability);
		subChrtcsMaintainability.put(SubCharacteristicEnum.CHANGEABILITY, changeability);
		subChrtcsMaintainability.put(SubCharacteristicEnum.STABILITY, stability);
		subChrtcsMaintainability.put(SubCharacteristicEnum.TESTABILITY, testability);
		
		assignEvaluationMetric(maintainabilityMetrics, tableModelMaintainability);
			
		Characteristic maintainability = characteristics.get(CharacteristicEnum.MAINTAINABILITY);
		maintainability.setSubcharacteristics(subChrtcsMaintainability);
		maintainability.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueMaintainability))));				
	}
	
	private void prepareEvaluationPortability() {
		Map<SubCharacteristicEnum, SubCharacteristic> subChrtcsPortability = new HashMap<SubCharacteristicEnum, SubCharacteristic>();
			
		SubCharacteristic adaptability = new SubCharacteristic();
		adaptability.setSubCharacteristicEnum(SubCharacteristicEnum.ADAPTABILITY);
		adaptability.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueAdaptability))));
		adaptability.setMetrics(getMetricsBySubChrtc(portabilityMetrics, SubCharacteristicEnum.ADAPTABILITY));		
			
		SubCharacteristic installability = new SubCharacteristic();
		installability.setSubCharacteristicEnum(SubCharacteristicEnum.INSTALLABILITY);
		installability.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueInstallability))));
		installability.setMetrics(getMetricsBySubChrtc(portabilityMetrics, SubCharacteristicEnum.INSTALLABILITY));
			
		SubCharacteristic coExistence = new SubCharacteristic();
		coExistence.setSubCharacteristicEnum(SubCharacteristicEnum.COEXISTENCE);
		coExistence.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueCoExistence))));
		coExistence.setMetrics(getMetricsBySubChrtc(portabilityMetrics, SubCharacteristicEnum.COEXISTENCE));

		SubCharacteristic replaceability = new SubCharacteristic();
		replaceability.setSubCharacteristicEnum(SubCharacteristicEnum.REPLACEABILITY);
		replaceability.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValueReplaceability))));
		replaceability.setMetrics(getMetricsBySubChrtc(portabilityMetrics, SubCharacteristicEnum.REPLACEABILITY));
			
		subChrtcsPortability.put(SubCharacteristicEnum.ADAPTABILITY, adaptability);
		subChrtcsPortability.put(SubCharacteristicEnum.INSTALLABILITY, installability);
		subChrtcsPortability.put(SubCharacteristicEnum.COEXISTENCE, coExistence);
		subChrtcsPortability.put(SubCharacteristicEnum.REPLACEABILITY, replaceability);
		
		assignEvaluationMetric(portabilityMetrics, tableModelPortability);
			
		Characteristic portability = characteristics.get(CharacteristicEnum.PORTABILITY);
		portability.setSubcharacteristics(subChrtcsPortability);
		portability.setWeight(BigDecimal.valueOf(Double.parseDouble(getText(txtValuePortability))));						
	}
	
	private void calculateCoordinates() {
		int xtemp = 70;
		int ytemp = 30;

		for (int i = 0; i < characteristics.size(); i++) {
			if (characteristics.size() > 3 && i == 3) {
				xtemp = 70;
				ytemp = 60;
			}

			int[] xy = { xtemp, ytemp };
			coordinates[i] = xy;
			xtemp += 180;
		}
	}
	
	private ImageIcon getIcon(IconEnum icon) {
		return new ImageIcon(getClass().getResource(icon.getLocation()));
	}
	
	private boolean percentFieldValidator(char newChar, String oldText) {
		return ((newChar < '0') || (newChar > '9') || oldText.length() == 3)
				|| Integer.valueOf(oldText + newChar) > 100 && (newChar != '\b');
	}
	
	private String getText(JTextField textField) {
		return textField.getText().isEmpty() ? "0" : textField.getText();
	}
	
	private BigDecimal addValueCharacteristics() {
		BigDecimal totalWeight = BigDecimal.ZERO;

		if (characteristics.containsKey(CharacteristicEnum.FUNCTIONALITY)) {
			totalWeight = BigDecimalUtil.add(totalWeight, BigDecimal
					.valueOf(Double.parseDouble(getText(txtValueFunctionality))));
		}

		if (characteristics.containsKey(CharacteristicEnum.RELIABILITY)) {
			totalWeight = BigDecimalUtil.add(totalWeight, BigDecimal
					.valueOf(Double.parseDouble(getText(txtValueReliability))));
		}

		if (characteristics.containsKey(CharacteristicEnum.USABILITY)) {
			totalWeight = BigDecimalUtil.add(totalWeight, BigDecimal
					.valueOf(Double.parseDouble(getText(txtValueUsability))));
		}

		if (characteristics.containsKey(CharacteristicEnum.EFFICIENCY)) {
			totalWeight = BigDecimalUtil.add(totalWeight, BigDecimal
					.valueOf(Double.parseDouble(getText(txtValueEfficiency))));
		}

		if (characteristics.containsKey(CharacteristicEnum.MAINTAINABILITY)) {
			totalWeight = BigDecimalUtil.add(totalWeight, BigDecimal
					.valueOf(Double.parseDouble(getText(txtValueMaintainability))));
		}

		if (characteristics.containsKey(CharacteristicEnum.PORTABILITY)) {
			totalWeight = BigDecimalUtil.add(totalWeight, BigDecimal
					.valueOf(Double.parseDouble(getText(txtValuePortability))));
		}
		
		return BigDecimalUtil.round(totalWeight, 0, RoundingMode.HALF_UP);
	}
	
	private BigDecimal addValueSubCharacteristics(JTextField... textFields) {
		BigDecimal totalWeight = BigDecimal.ZERO;

		for (JTextField txtSubCharacteristics : textFields) {
			totalWeight = BigDecimalUtil.add(totalWeight, BigDecimal
					.valueOf(Double.parseDouble(getText(txtSubCharacteristics))));			
		}
		
		return BigDecimalUtil.round(totalWeight, 0, RoundingMode.HALF_UP);
	}
	
	private void modifyValueCharacteristics(boolean enabled, String text,
			String totalText) {
		if (characteristics.containsKey(CharacteristicEnum.FUNCTIONALITY)) {
			txtValueFunctionality.setEditable(enabled);
			txtValueFunctionality.setText(text);
		}

		if (characteristics.containsKey(CharacteristicEnum.RELIABILITY)) {
			txtValueReliability.setEditable(enabled);
			txtValueReliability.setText(text);
		}

		if (characteristics.containsKey(CharacteristicEnum.USABILITY)) {
			txtValueUsability.setEditable(enabled);
			txtValueUsability.setText(text);
		}

		if (characteristics.containsKey(CharacteristicEnum.EFFICIENCY)) {
			txtValueEfficiency.setEditable(enabled);
			txtValueEfficiency.setText(text);
		}

		if (characteristics.containsKey(CharacteristicEnum.MAINTAINABILITY)) {
			txtValueMaintainability.setEditable(enabled);
			txtValueMaintainability.setText(text);
		}

		if (characteristics.containsKey(CharacteristicEnum.PORTABILITY)) {
			txtValuePortability.setEditable(enabled);
			txtValuePortability.setText(text);
		}
		
		lblTotalValueChrtcs.setText(totalText);
	}
	
	private boolean containsMetric(int idSelectedMetric, List<Metric> metrics) {
		for (Metric metric : metrics) {
			if (metric.getId() == idSelectedMetric) {
				return true;
			}
		}

		return false;
	}
	
	private void addMetric(CharacteristicEnum characteristic,
			List<Metric> metrics, DefaultTableModel tableModel) {
		callSelectorMetric(ActionEnum.SELECT, characteristic);
		Metric metric = getSelectedMetric();

		if (metric != null) {
			if (!containsMetric(metric.getId(), metrics)) {
				ScaleEnum notSelected = ScaleEnum.NOT_SELECTED;
				Object[] row = new Object[3];
				row[0] = metric.getDescription();
				row[1] = metric.getSubCharacteristicEnum().toString();
				row[2] = notSelected;
				tableModel.addRow(row);
				
				metric.setScale(notSelected);
				metrics.add(metric);
				setSelectedMetric(null);
			} else {
				JOptionPane.showMessageDialog(EvaluateChrtcs.this,
						"La métrica ya ha sido agregada",
						"Mensaje de información",
						JOptionPane.INFORMATION_MESSAGE);
			}
		}
	}
	
	private void removeMetric(int row, List<Metric> metrics) {
		metrics.remove(row);
	}

	private void refreshTable(JTable tblMetrics, List<Metric> metrics,
			DefaultTableModel tableModel) {
		tableModel.setDataVector(null, new String[] { "M\u00E9trica",
				"Sub-caracter\u00EDstica", "Evaluación" });

		for (Metric metric : metrics) {
			Object[] row = new Object[3];
			row[0] = metric.getDescription();
			row[1] = metric.getSubCharacteristicEnum().toString();
			row[2] = metric.getScale();
			tableModel.addRow(row);
		}
		
		tblMetrics.setModel(tableModel);
		tblMetrics.getColumnModel().getColumn(0).setResizable(false);
		tblMetrics.getColumnModel().getColumn(0).setPreferredWidth(155);
		tblMetrics.getColumnModel().getColumn(1).setResizable(false);
		tblMetrics.getColumnModel().getColumn(1).setPreferredWidth(90);
		tblMetrics.getColumnModel().getColumn(2).setResizable(false);
		tblMetrics.getColumnModel().getColumn(2).setPreferredWidth(30);
		
		DefaultCellEditor defaultCellEditor = new DefaultCellEditor(cbScales);
		tblMetrics.getColumnModel().getColumn(2).setCellEditor(defaultCellEditor);
	}
	
	private void modifyValueSubCharacteristics(boolean editable, String text,
			JLabel lblTotalValue, String totalText, JTextField... textFields) {
		for (JTextField txtSubCharacteristic : textFields) {
			txtSubCharacteristic.setEditable(editable);
			txtSubCharacteristic.setText(text);
		}

		lblTotalValue.setText(totalText);
	}
	
	public Metric getSelectedMetric() {
		return selectedMetric;
	}
	
	public void setSelectedMetric(Metric selectedMetric) {
		this.selectedMetric = selectedMetric;
	}
	
	private List<Metric> getMetricsBySubChrtc(List<Metric> chrtcsMetrics,
			SubCharacteristicEnum subCharacteristicEnum) {
		List<Metric> subChrtcMetrics = new ArrayList<Metric>();

		for (Metric metric : chrtcsMetrics) {
			if (subCharacteristicEnum.equals(metric.getSubCharacteristicEnum())) {
				subChrtcMetrics.add(metric);
			}
		}

		return subChrtcMetrics;
	}
}
